#ifndef _YM2612_CHIP_
#define _YM2612_CHIP_
//=======================================================================================================
// YM2612Chip
// Author: Landon Podbielski
// Description: This class simplifies usage of a YM2612 state, exposing its functionality 
//				in a way that makes it easy to adapt for VST's, Plugins, Emulators, etc. 
//				This class contains implementation specific to the YM2612 hardware specification,
//				and deals with register addresses and data packing in a very specific way. Don't
//				modify it unless you know what you're doing!
//
//				Throughout this class there will be diagrams which represent data layout:
//				
//				//FB_ALGORITHM
//				//------------------------------
//				//  0   1   2   3   4   5   6   7
//				//          |   FB  |   |  ALG  |
//				
//				This diagram specifies that we are dealing with 8 bits of data. Bits 2, 3, and 4
//				represent FB(channel feedback), while bits 5, 6, and 7 represend ALG( channel algorithm ).
//				These diagrams will always be followed by the packing of the specified information into
//				a chunk of data.
//
//				For more information regarding the data layout of parameters for the YM2612, you should
//				check out this website http://www.smspower.org/maxim/Documents/YM2612
//				
//-------------------------------------------------------------------------------------------------------

#include "YM2612Enum.h"
#include "YM2612StateData.h"
#include "ym2612\Fir_Resampler.h"

enum EmulationMode
{
	MODE_GXPLUS,
	MODE_GENS
};

//-------------------------------------------------------------------------------------------------------
//YM2612Chip - Wrapper for a YM2612 implementation
//-------------------------------------------------------------------------------------------------------
class I2612Impl;
class I2612Impl_Gens;
class YM2612Chip
{
public:
	YM2612Chip();
	~YM2612Chip();

	void Initialize( YM2612Clock clock = YM2612_NTSC, int soundRate = 44100, int improv = 0 );
	void Terminate();
	void Update( float **buf, int length );
	void SetParam( YM2612Param param, int op, unsigned char val, int channel );
	void SetAlgorithm( int alg, int channel );
	void WritePort0( int reg, int val );
	void WritePort1( int reg, int val );

	void WriteChannel( YM2612ChannelData data, int channel );
	void WriteOperator( YM2612Operator data, int op, int channel );

	void ClearNote( int channel );
	void FireNote( int channel );

	void SetEmulationMode( EmulationMode mode ) { _mode = mode; }

private:
	int GetRegister( YM2612Param param, int op, int channel );

	I2612Impl* _impl;
	I2612Impl_Gens* _implGens;
	EmulationMode _mode;

	//GXPlus implementation produces audio output at 53267hz, so we need 
	//to resample the audio output to 44100hz!
	Resampler _resampler;
	unsigned int _fmCyclesRatio;
	int _leftoverSamples;
	int _finishFrame;
	int _samples[4096];
};

#endif //_YM2612_CHIP_